import React, { useCallback, useImperativeHandle, useLayoutEffect, useRef } from "react";
import echarts, { type ECOption } from "./config";
import { type ECElementEvent, type EChartsType } from "echarts";
import { useShallow } from "zustand/react/shallow";
import { useGlobalStore } from "@/store/global";
import { useMenuStore } from "@/store/menus";
import { debounce } from "es-toolkit/function";
import { useUpdateEffect } from "ahooks";

interface Props {
  option: ECOption | any;
  renderer?: "canvas" | "svg";
  notMerge?: boolean;
  lazyUpdate?: boolean;
  onClick?: (event: ECElementEvent) => any;
  ref?: React.Ref<any>;
  className?: string;
}

const EChartInner: React.FC<Props> = (props) => {
  const containerRef = useRef<HTMLDivElement | null>(null);
  const echartsRef = useRef<EChartsType | null>(null);

  const { isCollapse } = useMenuStore(useShallow((state) => ({ isCollapse: state.isCollapse })));
  const { tabs, footer, maximize, menuSplit } = useGlobalStore(useShallow((state) => ({ tabs: state.tabs, footer: state.footer, maximize: state.maximize, menuSplit: state.menuSplit })));

  // 初始化echarts
  const initEcharts = (el: HTMLDivElement | null) => {
    if (!el) return;
    // @ts-expect-error EChartsType
    echartsRef.current = echarts.init(el, void 0, {
      renderer: props.renderer || "canvas",
      width: "auto",
      height: "auto"
    });

    setOption(props.option);
    // 监听屏幕缩放，重新绘制 echart 图表
    window.addEventListener("resize", resize);
    resize();
  };

  // 设置echarts
  const setOption = useCallback(
    (option: Props["option"]) => {
      if (!echartsRef.current) return;
      echartsRef.current?.setOption(option, props.notMerge, props.lazyUpdate);
      echartsRef.current?.on("click", (event: ECElementEvent) => props.onClick && props.onClick(event));
    },
    [props.notMerge, props.lazyUpdate]
  );

  // 缩放适配
  const resize = debounce(() => {
    echartsRef.current && echartsRef.current?.resize({ animation: { duration: 200 } });
  }, 200);

  // 销毁echarts
  const dispose = () => {
    if (!echartsRef.current) return;
    echartsRef.current && echartsRef.current.dispose();
    echartsRef.current = null;
    window.removeEventListener("resize", resize);
  };

  useLayoutEffect(() => {
    initEcharts(containerRef.current);
    return () => {
      dispose();
    };
  }, [props.option]);

  // 初始化首次渲染时不执行，只有依赖发生变化时才执行
  useUpdateEffect(() => {
    resize();
  }, [tabs, footer, maximize, menuSplit, isCollapse]);

  useImperativeHandle(props.ref, () => ({
    getEchartsRef: () => echartsRef.current
  }));

  return <div className={props.className} ref={containerRef} />;
};

export default React.memo(EChartInner);
